package cz.incad.psh.pshassign.server;

import cz.incad.psh.pshassign.server.search.PSHSearch;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.InputStream;
import java.io.StringWriter;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.commons.io.IOUtils;
import org.json.JSONArray;
import org.json.JSONObject;

/**
 *
 * @author Alberto Hernandez
 */
public class Assigner {
    
    private Logger logger = Logger.getLogger(this.getClass().getName());

    int ROWS = 200;
    JSONObject jsSolr;
    JSONObject jsonResponse;
    JSONObject jsonHl;
    String strength;
    public static int total = 0;
    public static int proccessed = 0;
    public static int failed = 0;
    public static boolean isCancelled = false;
    public static boolean isRunning = false;
    public static float hundred = (float) 100.0;
    
    BufferedWriter logFile;

    public static void main(String[] args) throws Exception {
        Assigner a = new Assigner();
        a.assign(true);
    }

    public static boolean getIsRunning() {
        return Assigner.isRunning;
    }

    public static int getProccessed() throws Exception {
        if (!Assigner.isRunning) {
            throw new Exception("not running");
        }
        if (Assigner.total == 0) {
            return 0;
        }
        return Math.round((Assigner.proccessed * hundred) / Assigner.total);
    }

    public static void setCancelled(boolean cancel) {
        Assigner.isCancelled = cancel;
    }

    public void assign(boolean update) throws Exception {
        Date start = new Date();
        logFile = new BufferedWriter(new FileWriter(Options.getOption("environment", "log_dir") + File.separator + "assigner.log"));
        System.out.println(new Date());
        int offset = 0;
        int numDocs = offset + 1;
        Assigner.proccessed = 0;
        Assigner.failed = 0;
        Assigner.total = 0;
        Assigner.isRunning = true;
        Assigner.isCancelled = false;
        String q = "*:*";
        if(update){
            q = "has_psh:false";
        }
        try {
            
            Invenio invenio = new Invenio();
            while (offset < numDocs && !Assigner.isCancelled) {
                
                String urlStr = Options.getOption("invenio", "solr")
                        + "/select?wt=json&fl=id&q="+q+"&rows=" + ROWS + "&start=" + offset;

                java.net.URL url = new java.net.URL(urlStr);

                InputStream is = url.openStream();
                StringWriter writer = new StringWriter();
                IOUtils.copy(is, writer, "UTF-8");
                jsSolr = new JSONObject(writer.toString());
                jsonResponse = jsSolr.getJSONObject("response");
                numDocs = jsonResponse.getInt("numFound");
                Assigner.total = numDocs;
                JSONArray docs = jsonResponse.getJSONArray("docs");
                strength = Options.getOption("assign", "strength");
                offset += ROWS;
                for (int i = 0; i < docs.length(); i++) {
                    String id = docs.getJSONObject(i).getString("id");
                    PSHSearch search = new PSHSearch();
                    logger.log(Level.INFO, "{0}.- Id: {1}", new Object[]{Assigner.proccessed, id});
//                    System.out.println("progress: "+ Assigner.getProccessed
                    try{
                        DocAssigner da = new DocAssigner(id);
                        String xml = da.asXml();
                        invenio.update(xml);
                        Assigner.proccessed++;
                    }catch(Exception ex){
                        Assigner.failed++;
                        logFile.write(id);
                        logFile.newLine();
                        logFile.write("Error on doc: " + ex.toString());
                        logFile.newLine();
                        logger.log(Level.WARNING, "Error on doc: " + id,  ex);
                        ex.printStackTrace();                       
                    }
                    if (Assigner.isCancelled) {
                        break;
                    }
                }
            }
            isRunning = false;
            Date end = new Date();
            System.out.println(end);
            logger.log(Level.WARNING, "Failed: {0}", Assigner.failed);
            logger.log(Level.INFO, "Total: {0}", Assigner.total);
            logger.log(Level.INFO, "progress: {0}", Assigner.getProccessed());
            
            if (logFile != null) {
                logFile.flush();
                logFile.close();
            }
            if (Assigner.isCancelled) {
                System.out.println("Proccess cancelled");
            }
        } catch (Exception ex) {
            isRunning = false;
            System.out.println(ex);
            throw new Exception(ex);
        }
    }
}
